package com.kamistoat.meimeichat.meimeichatserverapplication.netty.controller;

import com.kamistoat.meimeichat.meimeichatserverapplication.common.utils.R;
import com.kamistoat.meimeichat.meimeichatserverapplication.entity.MmcChatRecordEntity;
import com.kamistoat.meimeichat.meimeichatserverapplication.entity.MmcUserEntity;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.service.NettyUserService;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettyConstants;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettySocketChannelUtil;
import com.kamistoat.meimeichatserveraggrement.protocol.login.dto.ChatRecordDto;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据查询接口
 * 因为很多时候，服务器和客户端并不仅仅是双向主动通信，可能存在客户端需要问服务器查询数据的情况。
 * 例如，客户端查询和某个好友/群组的聊天记录
 */
@Controller
@RequestMapping("/meimeichatserver/webapi")
public class NettyInetController {

    @RequestMapping("test1")
    @ResponseBody
    public R test1(HttpServletRequest httpServletRequest) {
        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String s = headerNames.nextElement();
            System.out.println(s + " -- " + httpServletRequest.getHeader(s));
        }
//        System.out.println(httpServletRequest.getHeader("X-Real-Ip"));
//        System.out.println(httpServletRequest.getHeader("X-Natapp-Ip"));
//        System.out.println(httpServletRequest.getHeader("X-Forwarded-For"));
        System.out.println("remotePort -- " + httpServletRequest.getRemotePort());
        System.out.println("localPort -- " + httpServletRequest.getLocalPort());
        System.out.println("serverPort -- " + httpServletRequest.getServerPort());
        System.out.println("remoteAddr -- " + httpServletRequest.getRemoteAddr());
        return R.ok();
    }
    @RequestMapping("test2")
    @ResponseBody
    public R test2(HttpServletRequest httpServletRequest) {
        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String s = headerNames.nextElement();
            System.out.println(s + " -- " + httpServletRequest.getHeader(s));
        }
//        System.out.println(httpServletRequest.getHeader("X-Real-Ip"));
//        System.out.println(httpServletRequest.getHeader("X-Natapp-Ip"));
//        System.out.println(httpServletRequest.getHeader("X-Forwarded-For"));
        System.out.println("remotePort -- " + httpServletRequest.getRemotePort());
        System.out.println("localPort -- " + httpServletRequest.getLocalPort());
        System.out.println("serverPort -- " + httpServletRequest.getServerPort());
        return R.ok();
    }

    @Autowired
    NettyUserService nettyUserService;

    /**
     * 查询某个私聊对话框之前的聊天记录
     * 此接口为Web接口。当用户A将与B折叠的对话框打开时，使用该接口查询之前的聊天记录并填充对话框
     * 我当然知道正确做法应该是之前的聊天记录应该在本地保存，这样打开后直接用旧记录拼接新消息
     *
     * @param userId  调用该接口的用户Id
     * @param talkId  想要查询的对方Id
     * @param msgDate 只查询该时间之前的聊天信息
     */
    @RequestMapping("/queryFriendChatRecord")
    @ResponseBody
    public R queryFriendChatRecord(@RequestParam String userId, @RequestParam String talkId, @RequestParam String msgDate, HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getHeader("X-Real-Ip"));
        System.out.println(httpServletRequest.getHeader("X-Natapp-Ip"));
        System.out.println(httpServletRequest.getRemotePort());
        Date date = new Date(Long.parseLong(msgDate));
        List<ChatRecordDto> friendChatRecordDtoList = new ArrayList<>();
        List<MmcChatRecordEntity> mmcChatRecordEntities = nettyUserService.queryUserFriendChatRecord(userId, talkId);
        if (mmcChatRecordEntities == null || mmcChatRecordEntities.size() == 0) {
            return R.ok().put("chatList", friendChatRecordDtoList);
        }

        friendChatRecordDtoList = mmcChatRecordEntities.stream()
                // 只保留msgDate之前的消息
                .filter(entity -> entity.getMsgDate().getTime() < Long.parseLong(msgDate))
                // 对方信息已经提前查到，不需要再查，只保留核心记录信息即可
                .map(entity -> {
                    ChatRecordDto chatRecordDto = new ChatRecordDto();
                    chatRecordDto.setTalkId(talkId);
                    chatRecordDto.setMsgType(entity.getMsgType());
                    chatRecordDto.setMsgContent(entity.getMsgContent());
                    chatRecordDto.setMsgDate(entity.getMsgDate());
                    if (entity.getUserId().equals(userId)) {
                        // 自己发送的消息，MsgUserType=0
                        chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Myself.getCode());
                    } else {
                        // 好友发送的消息，MsgUserType=1
                        chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Friend.getCode());
                    }
                    return chatRecordDto;
                })
                .sorted((o1, o2) -> o2.getMsgDate().compareTo(o1.getMsgDate()))
                .collect(Collectors.toList());

        return R.ok().put("chatList", friendChatRecordDtoList);
    }

    /**
     * 登录时查询头像
     * @param userId
     * @return
     */
    @RequestMapping("/queryUserHead")
    @ResponseBody
    public R queryUserHead(@RequestParam String userId){
        if(userId == null || userId.equals("")){
            return R.error();
        }else{
            MmcUserEntity mmcUserEntity = nettyUserService.queryUserInfo(userId);
            if(mmcUserEntity == null){
                return R.error();
            }else{
                String userHead = mmcUserEntity.getUserHead();
                return R.ok().put("userHeadURI", userHead);
            }
        }
    }


    /**
     * 内部检查
     * @return
     */
    @RequestMapping("/queryServerChannelMap")
    @ResponseBody
    public R queryServerChannelMap(){
        ArrayList<String> userId_channel = new ArrayList<>();
        Set<String> userIdSet = NettySocketChannelUtil.USER_ID_CHANNEL_MAP.keySet();
        for (String userId : userIdSet) {
            Channel channel = NettySocketChannelUtil.USER_ID_CHANNEL_MAP.get(userId);
            if(channel != null){
                userId_channel.add(userId + "-" + channel.id().toString() + "-" + channel.remoteAddress().toString());
            }
        }

        ArrayList<String> userId_P2P = new ArrayList<>();
        Set<String> userIdSet_p2p = NettySocketChannelUtil.USER_ID_P2P_ADDRESS_MAP.keySet();
        for (String userId : userIdSet_p2p) {
            InetSocketAddress inetSocketAddress = NettySocketChannelUtil.USER_ID_P2P_ADDRESS_MAP.get(userId);
            if(inetSocketAddress != null){
                userId_P2P.add(userId + "-" + inetSocketAddress.toString());
            }
        }

        R res = R.ok();
        res.put("userId_channel", userId_channel);
        res.put("userId_P2P", userId_P2P);
        return res;
    }

}



